<?php

global $CFG;
require_once( $CFG->dirroot . 'mod/folio/model/page.php');
require_once( $CFG->dirroot . 'mod/folio/model/page_permission.php');

require_once('base.php');
require_once('decoration.php');
require_once('artifact.php');

class folio_PageAttachmentView extends folio_BaseView {

    private $page;

    function __construct( folio_page $page ) {
        $this->page = $page;

        // Load the results into cache.

        // Retrieve supporting objects for the page.
        $artifacts = folio_artifact::SelectWherePageIdent( $this->page->page_ident );
        $decorations = folio_decoration::SelectWherePageIdent( $this->page->page_ident );

        // Load decorations & artifacts according to their keys located
        //      in the page's attachment string.
        if( strlen( $this->page->attachments ) > 0 ) {
            $objects = split(",",$this->page->attachments);

            // Load each object.
            foreach( $objects as $o ) {

                // Load object
                if( substr( $o, 0, 8 ) == 'artifact' ) {
                    $object = new folio_ArtifactView(
                                    $artifacts[ substr( $o, 8 ) ] );
                } elseif ( substr( $o, 0, 10 ) == 'decoration' ) {
                    $object = new folio_DecorationView(
                                    $decorations[ substr( $o, 10 ) ] );
                } else {
                    trigger_error('Invalid attachments value ' . $o . ' for page_ident ' .
                                  $this->page->page_ident .
                                  ' for PageAttachmentView::html()', E_USER_ERROR);
                }

                // Add to cache
                $this->html .= "\n" . $object->html();
                $this->js .= "\n" . $object->js();
                $this->metatags = array_unique( array_merge(
                        $this->metatags, $object->metatags() ));
            }
        }

    }

}

class folio_PageBodyView extends folio_BaseView  {

    private $page;

    function __construct( folio_page $page ) {
        $this->page = $page;
        $this->html = $this->_html();
        $this->metatags = array(
            'mod/folio/lib/scriptaculous-js-1.7.0/lib/prototype.js',
            'mod/folio/lib/scriptaculous-js-1.7.0/src/scriptaculous.js',
            'mod/folio/js/view.js',
            'mod/folio/css/view.css'
        );

    }

    /**
     * Turns a page body into html, converting needed attachments and generating links.
     *
     * Translates [[Page Title]] to <a href=$url$username/page/$pagetitle/>>$pagetitle</a>.
     *     Note that we don't have a decode, as this should only be called by the view procedure.
     *    Encoded urls should not be stored in the database.
     *
     * Automatically removes invalid characters.
     *
     * Creates links to other user's wikis through [[username:page titles]]
     *
     * Adds in YOUTUBE links.  Should turn into an array instead of hardcoded, but this is
     *   just a quick fix.
     **/
    private function _html() {
        global $FOLIO_CFG;
        $user = folio_user::SelectWhereIdent( $this->page->user_ident );

        // Grab basic body.
        $body = $this->page->body;

        // Make links in the resulting text.
        $i = true;
        $url = url;

        // Create links
        while ( $i === true ) {
            $i = stripos( $body, '[[' );
            $end = stripos( $body, ']]' );
            $namespace = $user->username;
            $nametag = '';

            // Test find.
            if (!( $i === false | $end === false )) {
                // Translate title.

                $link = substr( $body, $i+2, $end -$i -2) ;

                // Find namespace for link.
                if ( $temp = stripos( $link, ':') ) {
                    $namespace = substr( $link, 0, $temp );
                    $link = substr( $link, $temp+1, strlen($link) - $temp );
                    $nametag = $namespace  . ':';
                }

                $body = substr( $body, 0, $i ) .
                    "<a href=\"{$url}{$namespace}/page/" .
                    folio_page::title_encode($link) .
                    "\">{$nametag}{$link}</a>" .
                    substr( $body, $end+2 );

                $i = true;
            }
        }

        // Swap out youtube videos
        $i = true;
        while ( $i === true ) {
            $i = stripos( $body, '{{' );
            $end = stripos( $body, '}}' );

            // Test find.
            if (!( $i === false | $end === false )) {
                // Translate title.
                $link = substr( $body, $i+10, $end -$i -10);
                $body = substr( $body, 0, $i ) .
                    '<object width="425" height="350"><param name="movie" value="http://www.youtube.com/v/' .
                    ($link) . '"></param><param name="wmode" value="transparent"></param>' .
                    '<embed src="http://www.youtube.com/v/' . ($link) . '" type="application/x-shockwave-flash"' .
                    'wmode="transparent" width="425" height="350"></embed></object>' .
                    substr( $body, $end+2 );

                $i = true;
            }
        }

        // Build wrapper and other controls
        $created = date( $FOLIO_CFG->gmstyle, intval($this->page->created) );

        if ( intval($this->page->creator_ident) < 1 ) {
            $creator = 'Anonymous';
        } else {
            $creator = folio_user::SelectWhereIdent($this->page->creator_ident);
            $creator = $creator->name;
        }

        // Building the html control.
        $body = <<< END
<div class="folio_page_view">
    <p>{$body}</p>
</div>
END;

/*
     <p class="folio_page_view_end">
        <span class="folio_page_view_creator">$creator</span>,
            <span class="folio_page_view_created">$created (GMT)</span>
    </p>
</div><!-- End folio_page_view -->

*/
        return $body;
    }

}

/**
 * Note that this class doesn't work with the BaseView because it
 *  is used to update the title of the Elgg page.
 */
class folio_PageBreadcrumb {

    /**
    * This function will display a breadcrumb control for a page.
    * It is formatted to display the page title as a breadcrumb control,
    * aka, the title of the current page will always be shown.
    *
    * @param folio_page $page
    * @return string Html to display
    */
    public function html( folio_page $page ) {
        return folio_PageBreadcrumb::recurse($page);
    }

    /**
    * Recurse to show parents
    * It is formatted to display the page title as a breadcrumb control,
    * aka, the title of the current page will always be shown.
    *
    * EXAMPLE OUTPUT
    *       <a><u>Page1</a><u> > <a><u>Page2</a></u> > ... > CurrentPage<br/>
    * @param folio_user $user Optional, include the owner of the page.
    * @param boolean $linktitle Optional, link the name of the current pag.e
    */
    private function recurse( folio_page $page, folio_user $user = NULL, $linktitle = false ) {
        //   Find the root page information.
        $url = url;
        $run_result = '';

        // Get user if needed
        if ( $user == NULL ) {
            $user = folio_user::SelectWhereIdent( $page->user_ident );
        }

        // Begin recursion.
        // The homepage for each user is signified by having a page_ident = parentpage_ident.
        //        Theoretically, some pages may not have a parent page, inwhich case, treat
        //        them as the root page.
        if ( $page->parentpage_ident != $page->page_ident OR $page->parentpage_ident == -1 ) {
            // Recurse
            $parentpage = folio_page::SelectWherePageIdent( ($page->parentpage_ident));
            if( !!$parentpage ) {
                $run_result = folio_PageBreadcrumb::recurse( $parentpage, $user, true );
            }
        }

        // Add link.
        if( $linktitle == true ) {
            return $run_result .
                "<a href=\"{$url}{$user->username}/page/" . folio_page::title_encode($page->title). "\">{$page->title}</a> &gt; ";
        } else {
            return trim($run_result . $page->title);
        }

    }
}

/**
 * Return a html formatted list of the children for the current page.
 * Takes into account security restrictions.
 */
class folio_PageChildrenList extends folio_BaseView {

    private $page;

    function __construct( folio_page $page ) {
        $this->page = $page;
        $this->html = $this->_html();
    }

    private function _html( ) {
        global $CFG;
        $url = url;

        $pages = folio_page::SelectWhereParentpageIdent($this->page->page_ident);
        $user = folio_user::SelectWhereIdent($this->page->user_ident);

        $html = '';

        if ( count($pages) > 0 ) {
            // Build html

            foreach ($pages as $childpage ) {
                // test permission
                if( $childpage->Permission('select') ){
                    // Load values.
                    $html .= "<li><a href=\"{$url}{$user->username}/page/" .
                        folio_page::title_encode($childpage->title). "\"" .
                        ">{$childpage->title}</a>\n";
                }
            }
        }

        $oChildren = __gettext('Child Pages');

        if( folio_page::InsertPermission( $user )  ) {
            // Add the 'newpage' link.
            $html .= "<li><a href=\"{$url}{$user->username}/page/" .
                folio_page::title_encode($this->page->title). "/addpage\"><b>" .
                __gettext("Add a new page under this one") .
                '</b></a><br/>';
        }

        if( $html <> '' ) {
            // Return html
            return <<< END
                <div class='folio_page_children'>
                    <h3>{$oChildren}</h3>
                    <ul>
                        {$html}
                    </ul>
                </div>
END;
        } else {
            return '';
        }

    }
}


class folio_PageTree extends folio_BaseView{

    private $page;

    function __construct( folio_page $page ) {
        $this->page = $page;
        $this->html = $this->_html();
        $this->metatags = array(
            'mod/folio/lib/yui_2.4.1/build/yahoo/yahoo-min.js',
            'mod/folio/lib/yui_2.4.1/build/event/event-min.js',
            'mod/folio/lib/yui_2.4.1/build/connection/connection-min.js',
            'mod/folio/lib/yui_2.4.1/build/treeview/treeview-min.js',
            'mod/folio/js/treeview.js',
            'mod/folio/css/treeview.css'
          );
    }

    /**
    * Public code that should be called to load a tree into the sidebar.
    * Returns text to be added to the sidebar.
    * SIDE EFFECT: Adds css and js links to metatags, calls sidebar_add
    *
    * @param folio_page $page The node being shown.
    * @param folio_user $user The owner of the page.
    * @return html
    */
    private function _html( ) {
        //    Note: Do not change the name of the root node to anything but root without
        //        also changing it in the helper functions in this file.
        global $CFG;

        $url = url;
        $p = 'folio_tree';

        $user = folio_user::SelectWhereIdent($this->page->user_ident);

        // Build javascript to load parent information.
        $buildNodes = folio_PageTree::getNodes( $this->page, $user );

        // Build the text body to go in the sidebar.
        $body = <<< END
<script type="text/javascript">

    var {$p}tree, {$p}currentIconMode;

    function {$p}treeInit() {
        {$p}currentIconMode=1;
       tree = new YAHOO.widget.TreeView("{$p}treeDiv1");
       tree.setDynamicLoad({$p}loadDataForNode); //, {$p}currentIconMode);

       var root = tree.getRoot();

       {$buildNodes}

       tree.draw();

    }



</script>

<div id='{$p}clear' class='{$p}clear'>
    <div id='{$p}tree' class="yui-skin-sam">
        <div id="{$p}treeDiv1"></div>
        <img src="{$url}mod/folio/image/tree_blankimage.jpg" onload="javascript:{$p}treeInit()"  />
    </div>
</div>



END;

       // Return text for the sidebar
        return $body;

    }

    /**
    * Recursively build the nodes for the tree control.
    *
    * NOTE: Depends upon the root js node being named 'root'.  This is the root node of the tree, not the root
    *    'Home Page' page.
    *
    * @param folio_page $page The page currently being built.
    * @param folio_user $user Owner of the page.
    * @param int $previous_page_ident Optional.  Previously called page for recursing.
    * @return string The HTML code of Nodes to be used by folio_control_tree
    **/
    private function getNodes( $page, $user, $previous_page_ident = -1) {

        $url = url;
        $prefix = 'folio_tree';

        // Build js for this page.
        //        Note that buildNode handles the permissions and senses if we're the homepage


        // Build js for any children of this page.
        $children = folio_page::SelectWhereParentpageIdent($page->page_ident);
        if( !!$children ) {
            $body = folio_PageTree::buildNode( $page, 'true', false, $user );
            foreach( $children as $child){
                // Add if not already created.
                if ( $child->page_ident != $previous_page_ident ) {
                    // Do they have children?
                    $childchild = folio_page::SelectWhereParentPageIdent($child->page_ident);
                    if( !$childchild ) {
                        $body .= folio_PageTree::buildNode( $child, 'false', true, $user );
                    } else {
                        $body .= folio_PageTree::buildNode( $child, 'false', false, $user );
                    }
                }
            }
        } else {
            $body = folio_PageTree::buildNode( $page, 'true', true, $user );
        }


        // Recurse, building parent node until we hit the homepage.
        if( !$page->IsHomepage() ) {
            $parentpage = folio_page::SelectWherePageIdent($page->parentpage_ident);
            if( !$parentpage) {
                trigger_error('Unable to load parent for page ' . $page->page_ident, E_USER_ERROR );
            }
            $body = folio_PageTree::getNodes( $parentpage, $user, $page->page_ident ) . $body;
        }

        // Return results.
        return $body;

    }

    /**
     * Create the js to build a node.
     *
     * @todo Check Permissions to avoid showing pages for invalid users
     * @param folio_page $page
     * @param string $expand True or False for if the node should be expanded by default.
     * @param boolean $no_children True if we know the node has no children.
     * @param folio_user $user Owner of the page.
     * @return string
     */
    public function buildNode( $page, $expand, $no_children, $user ) {
        global $CFG;
        $url = $CFG->wwwroot . $user->username . '/page/';

        $p = 'folio_tree';

        if( $page->IsHomepage() ) {
            $h = 'root';
        } else {
            $h = "{$p}Node{$page->parentpage_ident}";
        }

        $title = folio_PageTree::folio_tree_formattitle($page->title);
        $page_title= $url . folio_page::title_encode($page->title);

        $s = <<< END
var {$p}myObj{$page->page_ident} =
    {label: "{$title}", id:{$page->page_ident}, href: "{$page_title}" };
var {$p}Node{$page->page_ident} =
    new YAHOO.widget.TextNode({$p}myObj{$page->page_ident}, {$h}, {$expand});
    {$p}Node{$page->page_ident}.iconMode  = 1;
END;

        if ($no_children) {
            $s .= "{$p}Node{$page->page_ident}.dynamicLoadComplete = true;\n";
        }

        return $s;
    }

    /**
    * This function formats the title of a page in a suitable format for the treeview control
    *   As of Feb 2007, v.7 of Elgg forces a td.width declaration, which messes up the  yahoo treeview control
    *   As a fix, I do a duplicate declaration to set td.width=10px.  However, this means that the title needs to be
    *   forced to have the correct length.  So, I use non-breaking spaces to fill it out.  However, allowing some breaking
    *   spaces is a good idea, as otherwise it gets too long. So separate into chunks
    *
    * @param string $title Incoming title
    * @return string
    **/
    function folio_tree_formattitle( $title ) {
        // max len
        //return $title;
        $len = 25;
        $temp = '';

        $title = str_replace("\"", "'", trim($title) );
        $parts = explode(' ', $title);
        $title = '';

        foreach ( $parts as $part ) {
            if ( strlen( $temp ) == 0 ) {
                // Nothing in temp variable
                $temp = $part;
            } elseif ( ( strlen($temp) + strlen($part) ) < $len ) {
                // Can join
                $temp = $temp . '~' . $part;
            } else {
                // Too long.  Make new temp & move old temp to return value.
                $title = ltrim( $title . ' ' . $temp );
                $temp = $part;
            }
        }
        // Move last temp to title
        $title = str_replace( '~', '&nbsp;', trim( $title . ' ' . $temp ) );
        return $title;
    }

}




?>
